#include<stdio.h>
#include<stdlib.h>
#include "jni.h"
#include <android/log.h>
#define ARRAY_LENGTH 5
#define LOG_TAG "Dynamic.cpp"
#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

static const char *classPathName ="com/example/myapplicationtest/JNIClient2";

//第一步：定义函数
static  jint AddInt(JNIEnv* env,jobject clazz,jint a,jint b) {
	int result = a+b;
	return result;
}

static jint intArrayMethod(JNIEnv *env,jclass clazz,jintArray array) {
	int i,sum = 0;
	jsize len = (*env)->GetArrayLength(env,array);
	jint *body = (*env)->GetIntArrayElements(env,array,0);
	for(i=0;i<len;i++) {
	sum +=body[i];
	}
	
	//参数一：原始数据 	参数二：缓冲区数据	活动的形式
	(*env)->ReleaseIntArrayElements(env,array,body,0);
	return sum;
}

static jboolean booleanMethod(JNIEnv *env,jclass clazz,jboolean b) {
	return !b;
}
/*
 *原理讲解：
 *typedef struct{
 *const char* name; //the method's name of java
 *const char* signature; //signature about the params of methods 
 *void* fnptr; //the pointer of function
 *}
 */
//第二步：建立方法的映射
static JNINativeMethod methods[] = {
	{"AddInt","(II)I",(void*)AddInt},
	{"intArrayMethod","([I)I",(void*)intArrayMethod},
	{"booleanMethod","(Z)Z",(void*)booleanMethod},
	};


//第三步：注册方法
static int registerNativeMethods(JNIEnv *env,const char* classname,JNINativeMethod* gMethods,int numMethods) {
	jclass clazz;
	clazz = (*env)->FindClass(env,classname);
	//find the object of class 	
	 if(clazz==NULL) { 
		return JNI_FALSE;
	}
	
	if((*env)->RegisterNatives(env,clazz,gMethods,numMethods)<0){
		return JNI_FALSE;
	} 
	return JNI_TRUE;
}

static int registerNatives(JNIEnv* env){
ALOGE("Native registration unable to find class '%s'", "fei2");
	if(!registerNativeMethods(env,classPathName,methods,sizeof(methods) / sizeof(methods[0]))){
	return JNI_FALSE;
	}
	return JNI_TRUE;
}

//this is called by the VM when the shared library is first loaded.

typedef union {
	JNIEnv* env;	
	void* venv; 	
} UnionJNIEnvToVoid;

jint JNI_OnLoad(JavaVM* vm,void* reserved) {
	UnionJNIEnvToVoid uenv;
    uenv.venv = NULL;
    jint result = -1;
    JNIEnv* env = NULL;
    if((*vm)->GetEnv(vm,&uenv.venv,JNI_VERSION_1_4)!=JNI_OK){
	goto bail;
 }
	env = uenv.env;
	if(registerNatives(env) !=JNI_TRUE) {
 	goto bail; 
  }
	result = JNI_VERSION_1_4;
bail:
	return result;
}






